import {deepFullCopy, messages} from "share/common";
import React from 'react'
import { connect } from 'react-redux'
import baseService from 'share/base.service'
import 'styles/setting/expense-type/custom-expense-type.scss'
import { Menu, Col, Row, Button, Icon, Anchor, Spin, message, Dropdown, Modal, Select, Badge, Popover } from 'antd'
const Option = Select.Option;
const { Link } = Anchor;
import ListSort from 'components/list-sort'
import menuRoute from 'routes/menuRoute'
import expenseTypeService from 'containers/setting/expense-type/expense-type.service'
import { LanguageInput } from 'components/template'
import { setExpenseTypeSetOfBooks } from 'actions/setting'
import Ellipsis from 'ant-design-pro/lib/Ellipsis'
import defaultExpenseTypeIcon from 'images/expense/default-expense-type.png'
import Condition from 'components/condition';
import ExpenseTypeImportExport from './new-expense-type/expense-type-custom/expenst-type-import-export';
const { If } = Condition;

class CustomExpenseType extends React.Component{
  constructor(props) {
    super(props);
    this.state = {
      loading: true,
      sourceCategory: [],
      categorySorting: false,
      typeSorting: false,
      typeSortingIndex: -1,
      sortingCategory: false,  //loading
      sortingExpenseType: false,  //loading
      sortCategory: [],
      sortExpenseType: [],
      expenseTypeDetailPage: menuRoute.getRouteItem('expense-type-detail'),
      copyExpenseTypePage:menuRoute.getRouteItem('copy-expense-type'),
      nowEditCategory: {
        name: null,
        i18n: null
      },
      savingCategory: false,
      categoryEditVisible: false,
      setOfBooks: [],
      setOfBooksLoading: false,
      editBeforeCategoryInfo: null,  //费用大类编辑对象
    }
  }

  componentWillMount(){
    if(!this.props.expenseTypeSetOfBooks.id){
      this.props.dispatch(setExpenseTypeSetOfBooks({
        id: this.props.company.setOfBooksId,
        setOfBooksName: this.props.company.setOfBooksName
      }));
    }
    this.getSetOfBooks();
  }

  updateExpenseType = () => {
    this.getSourceCategory();
  };

  getSetOfBooks = () => {
    this.setState({ setOfBooksLoading: true });
    baseService.getSetOfBooksByTenant().then(res => {
      this.setState({ setOfBooks: res.data, setOfBooksLoading: false });
      let hasSetOfBooks = false;
      let id = this.props.company.setOfBooksId;
      res.data.map(item => {
        if(item.id === (this.props.expenseTypeSetOfBooks.id || this.props.company.setOfBooksId)){
          hasSetOfBooks = true;
          id = this.props.expenseTypeSetOfBooks.id;
          this.props.dispatch(setExpenseTypeSetOfBooks(item));
        }
      });
      if(!hasSetOfBooks){
        this.props.dispatch(setExpenseTypeSetOfBooks({
          id: this.props.company.setOfBooksId,
          setOfBooksName: this.props.company.setOfBooksName
        }));
      }
      this.getSourceCategory(id);
    })
  };

  getSourceCategory = (setOfBooksId = this.props.expenseTypeSetOfBooks.id) => {
    this.setState({ loading: true });
    baseService.getExpenseTypesBySetOfBooks(setOfBooksId, null, null).then(res => {
      res.data.rows.map(expenseCategory => {
        //如果是第三方费用类型，则不参与排序，放到最下方
        if (!expenseCategory.id) {
          expenseCategory.sequence = 999;
        }
      });
      let target = res.data.rows;
      let categoryCount = 0;
      target.map(expenseCategory => {
        if(expenseCategory.enabled){
          expenseCategory.sequence = categoryCount++;
          // expenseCategory.expenseTypes = expenseCategory.expenseTypes.sort((a, b) => a.sequence > b.sequence || -1);
          // fix bug 28218: 解决sort函数在sequence一样时，不同浏览器显示不同的排序结果
          for (let i = 0; i < expenseCategory.expenseTypes.length - 1; i++) {
            for (let j = 0; j < expenseCategory.expenseTypes.length - 1 - i; j++) {
              if (expenseCategory.expenseTypes[j].sequence > expenseCategory.expenseTypes[j + 1].sequence) {
                let temp = expenseCategory.expenseTypes[j];
                expenseCategory.expenseTypes[j] = expenseCategory.expenseTypes[j + 1];
                expenseCategory.expenseTypes[j + 1] = temp;
              }
            }
          }
          let expenseTypeCount = 0;
          expenseCategory.expenseTypes.map(expenseType => {
            if(expenseType.enabled){
              expenseType.sequence = expenseTypeCount++;
            }
          })
        }
      });
      this.setState({sourceCategory: target, loading: false});
    });
  };

  handleChangeSetOfBooks = (setOfBooksId) => {
    this.state.setOfBooks.map(item => {
      if(item.id === setOfBooksId)
        this.props.dispatch(setExpenseTypeSetOfBooks(item));
    });
    this.getSourceCategory(setOfBooksId);
  };

  handleSortCategory = (result) => {
    let sortCategory = [];
    result.map((item, index) => {
      sortCategory.push({
        id: item.key,
        sequence: index
      })
    });
    this.setState({ sortCategory });
  };

  handleSortExpense = (result) => {
    let sortExpenseType = [];
    result.map((item, index) => {
      sortExpenseType.push({
        id: item.key,
        sequence: index
      })
    });
    this.setState({ sortExpenseType });
  };

  finishCategorySort = (saveFlag) => {
    const { sortCategory } = this.state;
    if(saveFlag && sortCategory.length > 0){
      this.setState({ sortingCategory: true });
      expenseTypeService.sortCategory(sortCategory).then(res => {
        this.setState({ categorySorting: false, sortCategory: [], sortingCategory: false });
        message.success(messages('setting.key504'/*更新成功！正在刷新页面*/));
        this.getSourceCategory();
      })
    } else {
      this.setState({ categorySorting: false, sortCategory: [] })
    }
  };

  finishExpenseTypeSort = (saveFlag) => {
    const { sortExpenseType } = this.state;
    if(saveFlag && sortExpenseType.length > 0){
      this.setState({ sortingExpenseType: true });
      expenseTypeService.sortExpenseType(sortExpenseType).then(res => {
        this.setState({ typeSorting: false, sortExpenseType: [], sortingExpenseType: false });
        message.success(messages('setting.key504'/*更新成功！正在刷新页面*/));
        this.getSourceCategory();
      })
    } else {
      this.setState({ typeSorting: false, sortCategory: [] })
    }
  };

  handleEditExpenseType = (id) => {
    this.context.router.push(this.state.expenseTypeDetailPage.url.replace(':expenseTypeId', id))
  };

  handleCopyExpenseType = (e, expenseType) => {
    e.stopPropagation();
    expenseType.isAbleToCreatedManually
      ? this.context.router.push(this.state.copyExpenseTypePage.url.replace(/(\w*):expenseTypeId(.*):copy(.*)/, `$1${expenseType.id}$2copy`))
      : message.warning(messages('setting.key1834')/*该费用类型不可复制*/);
  };
  renderExpenseType = (expenseType, noClick) => {
    const { tenantMode } = this.props;
    return (
      <div className="expense-type-item" key={expenseType.id} onClick={noClick ? null : () => this.handleEditExpenseType(expenseType.id)}>
        <Row gutter={10}>
          <Col span={2}>
            <img src={expenseType.iconURL} onError={e => e.target.src = defaultExpenseTypeIcon}/>
          </Col>
          <Col span={tenantMode ? 9 : 13} className="expense-type-name">
            <Popover content={expenseType.name}>{expenseType.name}</Popover>
          </Col>
          <Col span={6}>
            {messages('setting.key505'/*类型*/)}：
            {expenseType.subsidyType === 0 && messages('setting.key506'/*非补贴*/)}
            {expenseType.subsidyType === 1 && messages('setting.key507'/*差旅补贴*/)}
            {expenseType.subsidyType === 2 && messages('setting.key508'/*日常补贴*/)}
          </Col>
          <Col span={3} style={{ textAlign: 'right' }}>
            <Badge status={expenseType.enabled ? 'success' : 'error'} style={{ height: 40 }}/>
            &nbsp;{expenseType.enabled ? messages('common.enabled') : messages('common.disabled')}
          </Col>
          <If value={tenantMode}>
            <Col span={4} style={{ textAlign: 'right' }}>
              <a style={!expenseType.isAbleToCreatedManually ? { color: '#cecece' } : {}}
                 onClick={noClick ? null : (e) => this.handleCopyExpenseType(e, expenseType)}>{messages('setting.key1430')/*复制*/}</a>
            </Col>
          </If>
        </Row>
      </div>
    )
  };

  handleClickEditMenu = (e, expenseTypeCategory) => {
    switch(e.key) {
      case 'rename':
        this.setState({
          nowEditCategory: expenseTypeCategory,
          categoryEditVisible: true,
          editBeforeCategoryInfo: deepFullCopy(expenseTypeCategory)
      });
        break;
      case 'delete':
        if (expenseTypeCategory.expenseTypes.length > 0)
          Modal.warning({
            title: messages('setting.key509'/*删除前请先移动该大类下的费用类型*/)
          });
        else
          expenseTypeService.deleteCategory(expenseTypeCategory.expenseTypeCategoryOID).then(res => {
            message.success(messages('common.delete.success',{name:''}));
            this.getSourceCategory();
          })
    }
  };

  renderButtonMenu = (expenseTypeCategory) => {
    return (
      <Menu onClick={e => this.handleClickEditMenu(e, expenseTypeCategory)}>
        {!expenseTypeCategory.defaultCategory &&
        <Menu.Item key="rename">{messages('setting.key510'/*重命名*/)}</Menu.Item>}
        <Menu.Item key="delete">{messages('common.delete')}</Menu.Item>
      </Menu>
    );
  };

  handleNewCategory = () => {
    this.setState({
      editBeforeCategoryInfo: null,
      nowEditCategory: {
        name: null,
        i18n: null
      }, categoryEditVisible: true
    })
  };

  handleEditCategory = () => {
    const { nowEditCategory } = this.state;
    let service =  expenseTypeService.editCategory;
    if(!nowEditCategory.name){
      message.error(messages('common.please.enter'));
      return ;
    }
    if(!nowEditCategory.id){
      nowEditCategory.enabled = true;
      nowEditCategory.setOfBooksId = this.props.expenseTypeSetOfBooks.id;
      nowEditCategory.sequence = 0;
      service = expenseTypeService.createCategory;
    }
    this.setState({ savingCategory: true });
    service(nowEditCategory).then(res => {
      this.setState({
        savingCategory: false,
        categoryEditVisible: false,
        nowEditCategory: {
          name: null,
          i18n: null
        }
      });
      message.success(messages('common.operate.success'));
      this.getSourceCategory();
    })
  };

  handleChangeI18n = (name, i18n) => {
    const { nowEditCategory } = this.state;
    nowEditCategory.name = name;
    nowEditCategory.i18n = {
      name: i18n
    };
    this.setState({
      nowEditCategory,
      savingCategory: !name
    });
  };
  //费用大类名字取消操作
  categoryNameCancel = () => {
    let {nowEditCategory, editBeforeCategoryInfo} = this.state;
    if (editBeforeCategoryInfo) {
      nowEditCategory.name = editBeforeCategoryInfo.name;
      editBeforeCategoryInfo.i18n ? nowEditCategory.i18n = deepFullCopy(editBeforeCategoryInfo.i18n) : ''
      editBeforeCategoryInfo = null;
    }
    this.setState({categoryEditVisible: false, nowEditCategory, editBeforeCategoryInfo})
  };

  render() {
    const { sourceCategory, categorySorting, typeSorting, typeSortingIndex, savingCategory, setOfBooksLoading,
      sortingCategory, sortingExpenseType, loading, categoryEditVisible, nowEditCategory, setOfBooks } = this.state;
    const { tenantMode } = this.props;
    return (
      <div className="custom-expense-type">
        {typeSorting ? <div className="sort-backdrop" /> : null}
        <Row gutter={20}>
          <Col span={6} className="left-container" style={{display:(categorySorting ? "none" : "block")}}>
            {setOfBooksLoading ? <Spin/> : (
              <Select
                className="set-of-books"
                value={this.props.expenseTypeSetOfBooks.id}
                onChange={this.handleChangeSetOfBooks}
                disabled={!tenantMode}
              >
                {setOfBooks.map(item => <Option key={item.id} value={item.id}>{item.setOfBooksName}</Option>)}
              </Select>
            )}
            {tenantMode && (
              <div className="fixed-button">
                <Button style={{ marginRight: 10 }} onClick={this.handleNewCategory}>
                  <Icon type="plus" />&nbsp;{messages('setting.key511'/*新增分类*/)}
                </Button>
                <Button onClick={() => this.setState({ categorySorting: true })}>
                  <Icon type="swap" />&nbsp;{messages('setting.key512'/*排序分类*/)}
                </Button>
              </div>
            )}
            <Anchor
              affix={false}
              className="anchor"
              getContainer={() => document.getElementsByClassName('right-container')[0]}
            >
              {sourceCategory.map(expenseTypeCategory => (
                <Link
                  href={`#${expenseTypeCategory.expenseTypeCategoryOID}`}
                  title={<Popover content={expenseTypeCategory.name}>
                    {expenseTypeCategory.name}
                  </Popover>}
                  key={expenseTypeCategory.expenseTypeCategoryOID}/>
              ))}
            </Anchor>
          </Col>
          { loading ? <Spin/> : (
            categorySorting ? (
              <Col span={24} style={{ padding: 0 }}>
                <Button
                  type="primary"
                  style={{ marginRight: 10 }}
                  onClick={() => this.finishCategorySort(true)}
                  loading={sortingCategory}
                >
                  {messages('setting.key513'/*完成*/)}
                </Button>
                <Button onClick={() => this.finishCategorySort(false)} disabled={sortingCategory}>
                  {messages('common.cancel')}
                </Button>
                <div style={{ position: 'relative' }}>
                  <ListSort
                    onChange={this.handleSortCategory}
                    dragClassName="list-drag-selected"
                  >
                    {sourceCategory.filter(item => item.enabled && item.id !== null).map(expenseTypeCategory => {
                      return (
                        <div
                          className="expense-type-category"
                          id={'' + expenseTypeCategory.expenseTypeCategoryOID}
                          key={expenseTypeCategory.id}
                        >
                          <div className="expense-type-category-title" style={{ cursor:'move' }}>
                            {expenseTypeCategory.name}&nbsp;
                            ({expenseTypeCategory.expenseTypes ? expenseTypeCategory.expenseTypes.length : 0})
                          </div>
                        </div>
                      )
                    })}
                  </ListSort>
                </div>
              </Col>
            ) : (
              <Col span={18} className="right-container">
                <ExpenseTypeImportExport updateExpenseType={this.updateExpenseType}/>
                {sourceCategory.map((expenseTypeCategory, index) => {
                  return (
                    <div
                      className={`expense-type-category${typeSorting && typeSortingIndex === index ? ' sorting-category' : ''}`}
                      id={'' + expenseTypeCategory.expenseTypeCategoryOID}
                      key={expenseTypeCategory.id}
                    >
                      <div className="expense-type-category-title">
                        <Row>
                          <Col span={tenantMode ? 18 : 24}>
                            <Ellipsis tooltip lines={1}>
                              {expenseTypeCategory.name}
                              ({expenseTypeCategory.expenseTypes ? expenseTypeCategory.expenseTypes.length : 0})
                            </Ellipsis>
                          </Col>
                          <Col span={6}>
                            {typeSorting && typeSortingIndex === index ? (
                              <div className="expense-type-category-operate">
                                <Button
                                  type="primary"
                                  style={{ marginRight: 10 }}
                                  onClick={() => this.finishExpenseTypeSort(true)}
                                  loading={sortingExpenseType}
                                >
                                  {messages('common.ok')}
                                </Button>
                                <Button onClick={() => this.finishExpenseTypeSort(false)} disabled={sortingExpenseType}>{messages('common.cancel')}</Button>
                              </div>
                            ) : (expenseTypeCategory.id && tenantMode && (
                              <div className="expense-type-category-operate">
                                <Dropdown overlay={this.renderButtonMenu(expenseTypeCategory)}>
                                  <Button style={{ marginRight: 10 }}>
                                    {messages('common.edit')} <Icon type="down" />
                                  </Button>
                                </Dropdown>
                                <Button onClick={() => this.setState({ typeSorting: true, typeSortingIndex: index })}
                                        disabled={!(expenseTypeCategory.expenseTypes && expenseTypeCategory.expenseTypes.length > 1)}>
                                  {messages('setting.key515'/*排序*/)}
                                </Button>
                              </div>
                            ))}
                          </Col>
                        </Row>
                      </div>
                      {typeSorting && typeSortingIndex === index ? (
                        <div className="expense-type-list">
                          <ListSort
                            onChange={this.handleSortExpense}
                            dragClassName="list-drag-selected"
                          >
                            {expenseTypeCategory.expenseTypes.map(expenseType => this.renderExpenseType(expenseType, true))}
                          </ListSort>
                        </div>
                      ) : (
                        <div className="expense-type-list">
                          {expenseTypeCategory.expenseTypes ? expenseTypeCategory.expenseTypes.map(expenseType =>
                            this.renderExpenseType(expenseType)
                          ) : null}
                        </div>
                      )}
                    </div>
                  )
                })}
              </Col>
            )
          ) }
        </Row>
        <Modal visible={categoryEditVisible}
               onCancel={this.categoryNameCancel}
               footer={
                 <p>
                   <Button onClick={this.categoryNameCancel}>{messages("common.cancel")}</Button>
                   <Button type={"primary"} disabled={savingCategory} onClick={this.handleEditCategory}>{messages("common.ok")}</Button>
                 </p>
               }>
          <div style={{
            lineHeight: '50px',
            fontWeight: 500,
            fontSize: 16
          }}>{messages('setting.key516'/*费用大类名称*/)}</div>
          <LanguageInput isEdit={!!nowEditCategory.id}
                         name={nowEditCategory.name}
                         i18nName={nowEditCategory.i18n ? nowEditCategory.i18n.name : null}
                         nameChange={this.handleChangeI18n}
                         inpRule={[{
                           length: 30,
                           language: "zh_cn"
                         }, {
                           length: 100,
                           language: "en"
                         }]}/>
        </Modal>
      </div>
    )
  }
}

CustomExpenseType.contextTypes = {
  router: React.PropTypes.object
};

function mapStateToProps(state) {
  return {
    company: state.login.company,
    expenseTypeSetOfBooks: state.setting.expenseTypeSetOfBooks,
    languageList: state.login.languageList,
    tenantMode: state.main.tenantMode
  }
}

export default connect(mapStateToProps)(CustomExpenseType)
